import React, { useState, useEffect, useRef, useReducer } from 'react'
import ControlTitle from '../ControlTitle'
import { Tabs, Spin, Button, Affix, message, Empty } from 'antd'
import QuotaLimitItem from '../QuotaLimitItem'
import { udConfigProvider, http } from '@/lib'
import apis from '@/apis/SystemSettings'
import matDataApis from '@/apis/SystemMasterDataManage'
import ButtonGroup from 'antd/lib/button/button-group'
import './style.scss'

const { TabPane } = Tabs

const monthOptions = [
  {
    title: '一月',
    value: 1,
  },
  {
    title: '二月',
    value: 2,
  },
  {
    title: '三月',
    value: 3,
  },
  {
    title: '四月',
    value: 4,
  },
  {
    title: '五月',
    value: 5,
  },
  {
    title: '六月',
    value: 6,
  },
  {
    title: '七月',
    value: 7,
  },
  {
    title: '八月',
    value: 8,
  },
  {
    title: '九月',
    value: 9,
  },
  {
    title: '十月',
    value: 10,
  },
  {
    title: '十一月',
    value: 11,
  },
  {
    title: '十二月',
    value: 12,
  },
]

// 方法组件里面使用useState更新数据会再次执行方法，会重置已保存的变量数据，所以需要将变量定义在方法外
let quotaLimitData = {}
let currentBrand = ''

const limitDataReducer = function (state, action) {
  const month = action.month
  const newData = { ...state }
  const index = action.index
  const values = action.values
  switch (action.type) {
    case 'change':
      newData[month][index] = { ...values, num: index + 1 }
      return newData
    case 'remove':
      newData[month].splice(index, 1)
      return newData
    case 'add':
      if (!newData[month]) {
        newData[month] = []
      }
      newData[month].push({monthBeforeNum: undefined, multiple: undefined, productGroupId: ''})
      return newData
    case 'equal':
      return values
    default:
      return state
    }
}

function QuotaLimitControl(props) {
  const { tabs } = props
  const [loading, setLoading] = useState(false)
  const [quotaLimitData, dispatchQuotaLimitData] = useReducer(limitDataReducer, {})
  const [matClassList, setMatClassList] = useState([])
  const pageContainer = udConfigProvider.ui.getPageContainer()
  /* 保存选择的月份，默认1月 */
  const currentMonthRef = useRef('1')
  /* 保存发生过更改的月份集合，提交保存的时候只提交有更改月份的数据 */
  const changeMonthsRef = useRef([])

  /* 切换月份等不更新state数据，但是需要触发重新渲染组件的情况调用 */
  const [, forceUpdate] = useReducer((c) => c + 1, 0)

  useEffect(() => {
    let code = tabs && tabs[0] ? tabs[0].value : undefined
    currentBrand = code
    code && getData()
    code && getMatClassList()
  }, [])

  const getData = (init = false) => {
    const month = currentMonthRef.current
    const params = { brandCode: currentBrand, month }
    /* 如果已经获取到对应月份的数据，则不请求数据，可以实现用户配置多个月份后一次性保存 */
    if (!init && quotaLimitData[month]&& quotaLimitData[month].length != 0) {
      return
    }
    setLoading(true)
    http.get(apis.QuotaLimitDetail, { params }).then(res => {
      const data = res.data.map(({monthBeforeNum, multiple, productGroupId}, index) => ({ monthBeforeNum, multiple, productGroupId, num: index + 1 })) || []
      let limitData = { ...quotaLimitData }
      if (init) {
        // 初始化请求制空保存的数据集合，避免切换品牌的时候更新不成功，导致的历史数据任然存在
        limitData = {}
        limitData[month] = data
      } else {
        limitData[month] = data
      }
      dispatchQuotaLimitData({ type: 'equal', values: limitData })
    }).finally(() => setLoading(false))
  }

  /* 获取物料分类列表数据 */
  const getMatClassList = () => {
    const brandCode = currentBrand
    const params = { conditions: { brandCode }, page: 1, size: 9999 }
    http.post(matDataApis.queryProductGroupPage, params).then(res => {
      const list = res?.data?.content?.map(({name: title, id: value}) => ({ title, value })) || []
      const allData = [{
        title: '全部',
        value: '',
        children: list
      }]
      setMatClassList(allData)
    })
  }

  const brandSwitchHandle = (key) => {
    currentBrand = key
    currentMonthRef.current = '1' // 初始化月份
    // 初始化月份的数据集合
    // TODO: 需要改成更改成功后执行getData()来优化代码
    dispatchQuotaLimitData({ type: 'equal', values: {} })
    getData(true)
    getMatClassList()
  }

  const monthSwitchHandle = (key) => {
    currentMonthRef.current = key
    // 强制重新渲染组件，用于获取 listData 正确数据
    forceUpdate()
    getData()

    // 初始化月份的数据集合，切换月份获取服务端最新数据方案
    // setQuotaLimitData({})
    // getData(true)
  }

  /* 子组件更新数据触发，更新状态数据 */
  const getItemData = (index, values) => {
    const month = currentMonthRef.current
    const changeMonths = changeMonthsRef.current
    // 保存变更了数据的月份
    if (!changeMonths.includes(month)) {
      changeMonths.push(month)
    }
    dispatchQuotaLimitData({ type: 'change', month, index, values })
  }

  /* 移除公式 */
  const removeFormulaHandle = (index) => {
    const month = currentMonthRef.current
    const changeMonths = changeMonthsRef.current
    // 保存变更了数据的月份
    if (!changeMonths.includes(month)) {
      changeMonths.push(month)
    }
    dispatchQuotaLimitData({ type: 'remove', month, index })
  }

  /* 增加公式 */
  const addFormulaHandle = () => {
    const month = currentMonthRef.current
    const changeMonths = changeMonthsRef.current
    // 保存变更了数据的月份
    if (!changeMonths.includes(month)) {
      changeMonths.push(month)
    }
    dispatchQuotaLimitData({ type: 'add', month })
  }

  const saveHandle = () => {
    console.log('quotaLimitData', quotaLimitData, currentBrand)
    for (const key in quotaLimitData) {
      if (quotaLimitData.hasOwnProperty(key)) {
        const data = quotaLimitData[key]
        const hasBlank = data.some(item => !item.monthBeforeNum || !item.multiple || (item.productGroupId !== '' && item.productGroupId.length == 0))
        if (hasBlank) {
          message.error(`请补全${key}月需要配置的数据`)
          return
        }
      }
    }
    let brandName = tabs.find(tab => tab.value === currentBrand).title
    /* 如果品牌是全称，则截取里面的简称 */
    brandName = brandName && brandName.length > 4 ? brandName.slice(4, 6) : brandName
    /**
     * Object.keys(quotaLimitData).filter(key=> Object.keys(quotaLimitData[key]).some(item => quotaLimitData[key][item]))
     * 筛选出有数据的月份
     * changeMonths.includes(key) 筛选只有操作变更过的月份数据
     */
    const changeMonths = changeMonthsRef.current
    const params = Object.keys(quotaLimitData).filter(key=> changeMonths.includes(key) && Object.keys(quotaLimitData[key]).some(item => quotaLimitData[key][item])).map(key => {
      const factors = quotaLimitData[key].map(item => {
        if (item.productGroupId.includes('') || !item.productGroupId) {
          // 没有物料分类或分类id为空，赋值全部分类id
          item.productGroupId = matClassList[0]?.children?.map(mat => mat.value)
        }
        return item
      })
      return { factors, brandCode: currentBrand, brandName, month: key }
    })
    setLoading(true)
    http.post(apis.UpdateQuotaLimit, params).then(res => {
      message.success('操作成功')
      // 清空保存的有更改数据的月份集合
      changeMonthsRef.current = []
    }).finally(() => setLoading(false))
  }

  let footer = (
    <div className='detail-footer'>
      <ButtonGroup>
        <Button type="primary" onClick={addFormulaHandle}>增加公式</Button>
        <Button type="primary" onClick={saveHandle}>保存</Button>
      </ButtonGroup>
    </div>
  )
  if (pageContainer) {
    footer = (
      <Affix offsetBottom={0} target={() => pageContainer}>
        {footer}
      </Affix>
    )
  }

  const listData = quotaLimitData[currentMonthRef.current] || []

  return (
    <>
      <ControlTitle title='计算配额公式配置' desc='用于控制各品牌公司约定配额执行标准上限值控制的规则配置' />
      {/* 品牌公司切换 */}
      <Tabs type='card' onChange={brandSwitchHandle}>
        {tabs.map(({ value, title }) => {
          return (
            <TabPane tab={title} key={value}></TabPane>
          )
        })}
      </Tabs>
      {/* 月份切换 */}
      <Tabs activeKey={currentMonthRef.current} onChange={monthSwitchHandle}>
        {monthOptions.map(({ value, title }) => {
          return (
            <TabPane tab={title} key={String(value)}></TabPane>
          )
        })}
      </Tabs>
      <Spin spinning={loading}>
        <div className="quota-limit-area">
          {listData.map((item, index) => {
            const data = item
            return <QuotaLimitItem lineNo={index + 1} key={index} canDelete={listData.length > 1} data={data || {}} matClassList={matClassList} transportData={(data) => getItemData(index, data)} removeFormulaHandle={() => removeFormulaHandle(index)} />
          })}
          {(!listData || listData.length == 0) && <Empty style={{marginBottom: 40}} />}
        </div>
      </Spin>
      {footer}
    </>
  )
}

export default React.memo(QuotaLimitControl)
